home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Tech Arsenal 1
/
Tech Arsenal (Arsenal Computer).ISO
/
tek-01
/
login.zip
/
LOGIN.C
< prev
next >
Wrap
C/C++ Source or Header
|
1991-02-03
|
9KB
|
354 lines
#include <stdio.h>
#include <conio.h>
#include <direct.h>
#include <dos.h>
#include <string.h>
#include <time.h>
#include <stdlib.h>
#include "login.h"
char *zgets(char *buffer, int echo);
int zputs(char *str);
struct usr *verify(); /* routine to validate user */
char *getfld(); /* pluck field n from a buffer */
char *motd, *passwd, *logfile; /* for default overrides */
int root = ROOT, debug = 0, logmode = 0, verbose = 0, message = 0;
void
main(argc, argv)
int argc;
char **argv;
{
struct usr *usr, home;
extern char *optarg;
extern int optind;
char linbuf[256];
int n, errflg = 0, c;
while ((c = getopt(argc, argv, "dvlm")) != EOF) {
switch (c) {
case 'd': /* enable debugging output */
++debug;
break;
case 'm': /* enable message of day output */
++message;
break;
case 'v': /* enable verbose output mode */
++verbose;
break;
case 'l': /* enable user activity logging mode */
++logmode;
break;
default: /* error */
errflg++;
break;
}
}
/* override the PASSWD file path */
if ((passwd = getenv("PASSWD")) == NULL)
passwd = PASSWD;
/* override the LOGFILE file path */
if ((logfile = getenv("LOGFILE")) == NULL)
logfile = LOGFILE;
/* override the MOTD file path */
if ((motd = getenv("MOTD")) == NULL)
motd = MOTD;
/* override the ROOT user id */
if (getenv("ROOT"))
root = atoi(getenv("ROOT"));
if (errflg) {
fprintf(stderr, USAGE);
exit(9);
}
/* set up master HOME environment, so that drive */
/* and directory changes are undone between users */
if (getcwd(home.home, 80) == NULL) /* current master directory */
error(4);
_dos_getdrive(&home.drive); /* use current logged drive */
fprintf(stderr, "%s", SIGNON);
/* stay here */
while (1) {
zputs("\n\rlogin: "); /* show login prompt */
zgets(linbuf, ECHO);
if (!strlen(linbuf))
continue;
/* validate user name */
if ((usr = verify(linbuf)) == (struct usr *)NULL)
zputs("\nlogin incorrect.\n");
else {
if (verbose)
usrinfo(usr); /* show user info */
if (message) /* show message of day */
domotd(motd);
if (n = setinfo(usr)) /* set user environment */
error(n); /* (even if root) */
if (usr->uid == root) /* if "root" ID, just exit */
exit(0);
else {
if (logmode)
loginfo(usr, 'I'); /* record user login */
showinfo(usr, "in");
system(usr->shell); /* execute command or shell */
showinfo(usr, "out");
if (logmode)
loginfo(usr, 'O'); /* record user log out */
}
if (n = setinfo(&home)) /* reset master environment */
error(n);
}
}
}
/* show user some handy info */
showinfo(struct usr *u, char *m)
{
time_t t;
time (&t);
fprintf(stderr, "\nLogged %s: %.24s Drive=%c: Path=%s\n",
m, ctime(&t), u->drive+'@', u->home);
return (0);
}
/* set user environment per the password file */
setinfo(struct usr * u)
{
unsigned a;
_dos_setdrive(u->drive, &a); /* set drive */
_dos_getdrive(&a); /* verify drive was selected */
if (a != u->drive) /* error */
return (1);
if (chdir(u->home)) /* set new home directory */
return (2);
return (0);
}
/* display user environment per the password file */
usrinfo(struct usr * u)
{
char *p;
fprintf(stderr, "\n");
fprintf(stderr, "name.......%s\n", u->name); /* 0 */
fprintf(stderr, "user id....%d\n", u->uid); /* 1 */
p = decrypt(u->passwd);
if (debug)
fprintf(stderr, "password...%s\n", p); /* 2 */
if (p)
free(p);
fprintf(stderr, "drive......%c\n", u->drive + '@'); /* 3 */
fprintf(stderr, "home.......%s\n", u->home); /* 4 */
fprintf(stderr, "shell......%s\n", u->shell); /* 5 */
}
/* log user activity in log file */
loginfo(struct usr * u, char m)
{
FILE *fp;
char db[9];
char tb[9];
/* open log file */
if ((fp = fopen(logfile, "a+")) == NULL) {
error(5);
return(0);
}
/* if file is new, add header */
if ((filelength(fileno(fp))) == 0) {
fprintf(fp, "T| Date Time | User Name |ID#|D| User Home Directory | Command/Shell\n");
fprintf(fp, "-+-----------------+---------------+---+-+---------------------+------------------\n");
/* I|02/01/91 21:18:36|mfl | 1|D|\games |C:\COMMAND.COM */
/* O|02/01/91 21:18:36|mfl | 1|D|\games |C:\COMMAND.COM */
}
_strdate(db); /* get date */
_strtime(tb); /* get time */
fprintf(fp, "%c|%s %s|%-15s|%3d|%c|%-21s|%-20s\n",
m, db, tb, u->name, u->uid, u->drive + '@', u->home, u->shell);
fclose(fp);
return (0);
}
domotd(f)
char *f;
{
FILE *fp;
char linbuf[256];
/* open daily message file */
if ((fp = fopen(f, "r")) == NULL) {
error(7);
return (0);
}
/* no lines in file */
if ((filelength(fileno(fp))) == 0) {
error(8);
return (0);
}
fprintf(stderr, "\n\r");
/* read lines from the MOTD file */
while (fgets(linbuf, BUFSIZ, fp))
fprintf(stderr, "%s", linbuf);
fclose(fp);
zputs("\n\rPress any key...");
zgetch();
}
/* validate user, assign default values per the password file */
struct usr *
verify(char *l)
{
FILE *fp;
static struct usr u;
char linbuf[256];
char *comspec, *p, shell[80];
int found = 0;
/* open password file */
if ((fp = fopen(passwd, "r")) == NULL) {
error(3);
return ((struct usr *)NULL);
}
/* read lines from the PASSWD file */
while (!found && fgets(linbuf, BUFSIZ, fp)) {
memset(&u, '\0', sizeof (struct usr)); /* clean up structure */
if (*linbuf == '#') /* '#' denotes comment */
continue;
p = getfld(linbuf, 0, ':'); /* user name */
strcpy(u.name, p); /* user name */
if (p)
free(p);
if (!strcmp(u.name, l)) /* name matches */
found = 1;
else
continue;
if ((p = strchr(linbuf, '\n')) != NULL) /* zap new-lines */
*p = '\0';
p = getfld(linbuf, 1, ':'); /* user ID */
u.uid = atoi(p); /* user ID */
if (p)
free(p);
p = getfld(linbuf, 2, ':'); /* user password */
strcpy(u.passwd, p); /* user password */
if (p)
free(p);
p = getfld(linbuf, 3, ':'); /* disk drive */
u.drive = *p == '\0' ? 0 : *p - '@'; /* set to 0 if none */
if (p)
free(p);
p = getfld(linbuf, 4, ':'); /* home directory */
strcpy(u.home, p); /* home directory */
if (p)
free(p);
p = getfld(linbuf, 5, ':'); /* command/shell */
strcpy(shell, p); /* command/shell */
if (p)
free(p);
if (*u.home == '\0') /* no HOME specified */
if (getcwd(u.home, 80) == NULL) /* current directory */
error(4);
}
/* prompt for password for invalid names and if a password is specified */
if (!found || *u.passwd != '\0') { /* password required or */
zputs("\npassword: "); /* invalid name entered */
zgets(linbuf, NOECHO);
}
/* if name and password (if any) matches */
p = decrypt(u.passwd);
if (found && (!strcmp(p, linbuf) || *u.passwd == '\0')) {
if (u.drive == 0) /* no drive specified */
_dos_getdrive(&u.drive); /* use current drive */
if ((comspec = (char *) getenv("COMSPEC")) == NULL) {
comspec = "X:\command.com";
*comspec = (char )u.drive + '@'; /* use current drive */
}
strcpy(u.shell, shell); /* execute whatever as default */
/* if "shell" specified, use COMSPEC to find "command.com" */
if (!strncmp(strupr(shell), "SHELL", 5))
strcpy(u.shell, comspec);
else if (p = strchr(shell, '.')) {
if (!strcmp(strupr(p), ".BAT")) /* execute batch file */
sprintf(u.shell, "%s /C %s", comspec, shell);
}
} else
found = 0;
if (p)
free(p);
fclose(fp);
return (found ? &u : (struct usr *) NULL);
}
char *
zgets(char *str, int echo)
{
char c, *save = str;
while ((c = zgetch()) != '\n') {
*str++ = c;
if (echo)
putch(c);
}
*str = '\0';
return save;
}
int
zgetch()
{
char c;
c = bdos(7, 0, 0);
return (c == '\r') ? '\n' : c;
}
zputs(char *str)
{
char c;
while (c = *str++) {
if (c == '\n')
putch('\r');
putch(c);
}
return 0;
}